home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_se / manifest_array.e < prev    next >
Text File  |  2000-03-25  |  13KB  |  502 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
  4. --                       http://SmallEiffel.loria.fr
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License
  11. -- for  more  details.  You  should  have  received a copy of the GNU General
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class MANIFEST_ARRAY
  17.    --
  18.    -- Like :  << foo , bar >>
  19.    --
  20.  
  21. inherit EXPRESSION;
  22.  
  23. creation make
  24.  
  25. feature
  26.  
  27.    start_position: POSITION;
  28.          -- Of first character '<'.
  29.  
  30.    list: ARRAY[EXPRESSION];
  31.          -- Void or elements in the array.
  32.  
  33.    result_type: TYPE_ARRAY;
  34.          -- Computed according to the actual `list'.
  35.  
  36.    is_manifest_array: BOOLEAN is true;
  37.  
  38.    is_current: BOOLEAN is false;
  39.  
  40.    is_writable: BOOLEAN is false;
  41.  
  42.    is_manifest_string: BOOLEAN is false;
  43.  
  44.    is_result: BOOLEAN is false;
  45.  
  46.    is_void: BOOLEAN is false;
  47.  
  48.    is_static: BOOLEAN is false;
  49.  
  50.    precedence: INTEGER is 2;
  51.  
  52.    can_be_dropped: BOOLEAN is false;
  53.  
  54.    c_simple: BOOLEAN is false;
  55.  
  56.    isa_dca_inline_argument: INTEGER is 0;
  57.  
  58.    static_result_base_class: BASE_CLASS is
  59.       do
  60.          Result := small_eiffel.get_class(as_array);
  61.       end;
  62.  
  63.    static_value: INTEGER is
  64.       do
  65.       end;
  66.  
  67.    dca_inline_argument(formal_arg_type: TYPE) is
  68.       do
  69.       end;
  70.  
  71.    is_pre_computable: BOOLEAN is
  72.       local
  73.          i: INTEGER;
  74.          e: EXPRESSION;
  75.       do
  76.          if list = Void then
  77.             Result := true;
  78.          elseif result_type.generic_list.item(1).is_string then
  79.             from
  80.                Result := true;
  81.                i := list.upper;
  82.             until
  83.                not Result or else i = 0
  84.             loop
  85.                e := list.item(i);
  86.                Result := e.is_pre_computable;
  87.                i := i - 1;
  88.             end;
  89.          end;
  90.       end;
  91.  
  92.    assertion_check(tag: CHARACTER) is
  93.       local
  94.          i: INTEGER;
  95.          e: EXPRESSION;
  96.       do
  97.          if list /= Void then
  98.             from
  99.                i := list.upper;
  100.             until
  101.                i = 0
  102.             loop
  103.                e := list.item(i);
  104.                e.assertion_check(tag);
  105.                i := i - 1;
  106.             end;
  107.          end;
  108.       end;
  109.  
  110.    afd_check is
  111.       local
  112.          i: INTEGER;
  113.       do
  114.          if list /= Void then
  115.             from
  116.                i := list.upper;
  117.             until
  118.                i = 0
  119.             loop
  120.                list.item(i).afd_check;
  121.                i := i - 1;
  122.             end;
  123.          end;
  124.       end;
  125.  
  126.    frozen mapping_c_target(target_type: TYPE) is
  127.       do
  128.          cpp.put_string(fz_b7);
  129.          cpp.put_integer(target_type.id);
  130.          cpp.put_string(fz_b8);
  131.          compile_to_c;
  132.          cpp.put_character(')');
  133.       end;
  134.  
  135.    frozen mapping_c_arg(formal_arg_type: TYPE) is
  136.       do
  137.          compile_to_c;
  138.       end;
  139.  
  140.    collect_c_tmp is
  141.       do
  142.       end;
  143.  
  144.    compile_to_c is
  145.       local
  146.          i: INTEGER;
  147.          formal_type, actual_type: TYPE;
  148.          adr: BOOLEAN;
  149.          e: EXPRESSION;
  150.       do
  151.          manifest_array_pool.c_call(result_type);
  152.          formal_type := result_type.generic_list.item(1).run_type;
  153.          cpp.put_character('(');
  154.          if list = Void then
  155.             cpp.put_character('0');
  156.          else
  157.             adr := formal_type.is_user_expanded;
  158.             cpp.put_integer(list.upper);
  159.             from
  160.                i := 1;
  161.             until
  162.                i > list.upper
  163.             loop
  164.                cpp.put_string(fz_b9);
  165.                if adr then
  166.                   cpp.put_character('&');
  167.                end;
  168.                e := list.item(i);
  169.                actual_type := e.result_type.run_type;
  170.                e.compile_to_c;
  171.                i := i + 1;
  172.             end;
  173.          end;
  174.          cpp.put_character(')');
  175.       end;
  176.  
  177.    c_declare_for_old is
  178.       local
  179.          i: INTEGER;
  180.       do
  181.          if list /= Void then
  182.             from
  183.                i := list.upper;
  184.             until
  185.                i = 0
  186.             loop
  187.                list.item(i).c_declare_for_old;
  188.                i := i - 1;
  189.             end;
  190.          end;
  191.       end;
  192.  
  193.    compile_to_c_old is
  194.       local
  195.          i: INTEGER;
  196.       do
  197.          if list /= Void then
  198.             from
  199.                i := list.upper;
  200.             until
  201.                i = 0
  202.             loop
  203.                list.item(i).compile_to_c_old;
  204.                i := i - 1;
  205.             end;
  206.          end;
  207.       end;
  208.  
  209.    compile_to_jvm_old is
  210.       local
  211.          i: INTEGER;
  212.       do
  213.          if list /= Void then
  214.             from
  215.                i := list.upper;
  216.             until
  217.                i = 0
  218.             loop
  219.                list.item(i).compile_to_jvm_old;
  220.                i := i - 1;
  221.             end;
  222.          end;
  223.       end;
  224.  
  225.    compile_target_to_jvm, compile_to_jvm is
  226.       local
  227.          rt, elt_type: TYPE;
  228.          i, idx, space: INTEGER;
  229.          rc: RUN_CLASS;
  230.          idx_rc: INTEGER;
  231.          cp: like constant_pool;
  232.          ca: like code_attribute;
  233.       do
  234.          cp := constant_pool;
  235.          ca := code_attribute;
  236.          rt := result_type.run_type;
  237.          rc := rt.run_class;
  238.          elt_type := rt.generic_list.item(1).run_type;
  239.          idx_rc := rc.jvm_constant_pool_index;
  240.          rc.jvm_basic_new;
  241.          -- Set lower :
  242.          idx := cp.idx_fieldref4(idx_rc,as_lower,fz_i);
  243.          ca.opcode_dup;
  244.          ca.opcode_iconst_1;
  245.          ca.opcode_putfield(idx,-2);
  246.          -- Set upper :
  247.          idx := cp.idx_fieldref4(idx_rc,as_upper,fz_i);
  248.          ca.opcode_dup;
  249.          if list = Void then
  250.             ca.opcode_iconst_0;
  251.          else
  252.             ca.opcode_push_integer(list.count);
  253.          end;
  254.          ca.opcode_putfield(idx,-2);
  255.          -- Set capacity :
  256.          idx := cp.idx_fieldref4(idx_rc,as_capacity,fz_i);
  257.          ca.opcode_dup;
  258.          if list = Void then
  259.             ca.opcode_iconst_0;
  260.          else
  261.             ca.opcode_push_integer(list.count);
  262.          end;
  263.          ca.opcode_putfield(idx,-2);
  264.          -- Set storage :
  265.          idx := cp.idx_fieldref4(idx_rc,as_storage,sd(elt_type));
  266.          ca.opcode_dup;
  267.          if list = Void then
  268.             ca.opcode_aconst_null;
  269.          else
  270.             ca.opcode_push_integer(list.count);
  271.             elt_type.jvm_xnewarray;
  272.             from
  273.                i := 1;
  274.             until
  275.                i > list.upper
  276.             loop
  277.                ca.opcode_dup;
  278.                ca.opcode_push_integer(i - 1);
  279.                space := list.item(i).compile_to_jvm_into(elt_type);
  280.                elt_type.jvm_xastore;
  281.                i := i + 1;
  282.             end;
  283.          end;
  284.          ca.opcode_putfield(idx,-2);
  285.       end;
  286.  
  287.    jvm_branch_if_false: INTEGER is
  288.       do
  289.       end;
  290.  
  291.    jvm_branch_if_true: INTEGER is
  292.       do
  293.       end;
  294.  
  295.    compile_to_jvm_into(dest: TYPE): INTEGER is
  296.       do
  297.          Result := 1;
  298.          compile_to_jvm;
  299.       end;
  300.  
  301.    use_current: BOOLEAN is
  302.       local
  303.          i: INTEGER;
  304.       do
  305.          if list /= Void then
  306.             from
  307.                i := list.upper;
  308.             until
  309.                i = 0 or else Result
  310.             loop
  311.                Result := list.item(i).use_current;
  312.                i := i - 1;
  313.             end;
  314.          end;
  315.       end;
  316.  
  317.    stupid_switch(r: ARRAY[RUN_CLASS]): BOOLEAN is
  318.       local
  319.          i: INTEGER;
  320.       do
  321.          Result := true;
  322.          if list /= Void then
  323.             from
  324.                i := list.upper;
  325.             until
  326.                not Result or else i = 0
  327.             loop
  328.                Result := list.item(i).stupid_switch(r);
  329.                i := i - 1;
  330.             end;
  331.          end;
  332.       end;
  333.  
  334.    to_runnable(ct: TYPE): like Current is
  335.       local
  336.          i: INTEGER;
  337.          e: EXPRESSION;
  338.          elt: TYPE;
  339.       do
  340.          if current_type = Void then
  341.             current_type := ct;
  342.             if list = Void then
  343.                elt := type_any;
  344.             else
  345.                from
  346.                   i := list.upper;
  347.                until
  348.                   i = 0
  349.                loop
  350.                   e := list.item(i).to_runnable(ct);
  351.                   if e = Void then
  352.                      eh.add_position(start_position);
  353.                      error(list.item(i).start_position,
  354.                            "Bad expression in manifest array.");
  355.                      i := 0;
  356.                   else
  357.                      list.put(e,i);
  358.                      if elt = Void then
  359.                         elt := e.result_type;
  360.                      else
  361.                         elt := elt.smallest_ancestor(e.result_type);
  362.                      end;
  363.                      i := i - 1;
  364.                   end;
  365.                end;
  366.             end;
  367.             if nb_errors = 0 then
  368.                elt := elt.run_type;
  369.                !!result_type.make(start_position,elt);
  370.                result_type.run_class.set_at_run_time;
  371.                result_type.load_basic_features;
  372.                Result := Current;
  373.                if list /= Void then
  374.                   from
  375.                      i := list.upper;
  376.                   until
  377.                      i = 0
  378.                   loop
  379.                      e := list.item(i);
  380.                      e := conversion_handler.implicit_cast(e,elt);
  381.                      list.put(e,i);
  382.                      i := i - 1;
  383.                   end;
  384.                end;
  385.                manifest_array_pool.register(result_type);
  386.             end;
  387.          elseif list = Void then
  388.             Result := Current;
  389.          else
  390.             !!Result.make(start_position,list.twin);
  391.             Result := Result.to_runnable(ct);
  392.          end;
  393.       end;
  394.  
  395.    bracketed_pretty_print is
  396.       do
  397.          fmt.put_character('(');
  398.          pretty_print;
  399.          fmt.put_character(')');
  400.       end;
  401.  
  402.    pretty_print is
  403.       local
  404.          i: INTEGER;
  405.       do
  406.          fmt.put_string(fz_c_shift_left);
  407.          fmt.level_incr;
  408.          if list /= Void then
  409.             from
  410.                i := 1;
  411.             until
  412.                i > list.upper
  413.             loop
  414.                list.item(i).pretty_print;
  415.                i := i + 1;
  416.                if i <= list.upper then
  417.                   fmt.put_character(',');
  418.                end;
  419.             end;
  420.          end;
  421.          fmt.put_string(fz_c_shift_right);
  422.          fmt.level_decr;
  423.       end;
  424.  
  425.    print_as_target is
  426.       do
  427.          fmt.put_character('(');
  428.          pretty_print;
  429.          fmt.put_character(')');
  430.          fmt.put_character('.');
  431.       end;
  432.  
  433.    short is
  434.       local
  435.          i: INTEGER;
  436.       do
  437.          short_print.hook_or("op_ma",fz_c_shift_left);
  438.          if list /= Void then
  439.             from
  440.                i := 1;
  441.             until
  442.                i > list.upper
  443.             loop
  444.                list.item(i).short;
  445.                i := i + 1;
  446.                if i <= list.upper then
  447.                   short_print.hook_or("ma_sep",",");
  448.                end;
  449.             end;
  450.          end;
  451.          short_print.hook_or("cl_ma",fz_c_shift_right);
  452.       end;
  453.  
  454.    short_target is
  455.       do
  456.          bracketed_short;
  457.          short_print.a_dot;
  458.       end;
  459.  
  460.    jvm_assign is
  461.       do
  462.       end;
  463.  
  464. feature {NONE}
  465.  
  466.    current_type: TYPE;
  467.  
  468.    make(sp: like start_position; l: like list) is
  469.       require
  470.          not sp.is_unknown;
  471.          l /= Void implies not l.is_empty and l.lower =1;
  472.       do
  473.          start_position := sp;
  474.          list := l;
  475.       ensure
  476.          start_position = sp;
  477.          list = l;
  478.       end;
  479.  
  480.    sd(elt_type: TYPE): STRING is
  481.          -- The JVM descriptor for `storage'.
  482.       do
  483.          tmp_string.clear;
  484.          tmp_string.extend('[');
  485.          elt_type.jvm_descriptor_in(tmp_string);
  486.          Result := tmp_string;
  487.       end;
  488.  
  489.    tmp_string: STRING is
  490.       once
  491.          !!Result.make(16);
  492.       end;
  493.  
  494. invariant
  495.  
  496.    not start_position.is_unknown;
  497.  
  498.    list /= Void implies not list.is_empty and list.lower = 1;
  499.  
  500. end -- MANIFEST_ARRAY
  501.  
  502.